// Copyright (c) 2010-2024, Lawrence Livermore National Security, LLC. Produced
// at the Lawrence Livermore National Laboratory. All Rights reserved. See files
// LICENSE and NOTICE for details. LLNL-CODE-806117.
//
// This file is part of the MFEM library. For more information and source code
// availability visit https://mfem.org.
//
// MFEM is free software; you can redistribute it and/or modify it under the
// terms of the BSD-3 license. We welcome feedback and contributions, see file
// CONTRIBUTING.md for details.

#include "mfem.hpp"
#include "unit_tests.hpp"

void Scale(std::vector<double>& x, std::vector<double>& w)
{
   const int n = x.size();
   for (int i = 0 ; i < n ; ++i)
   {
      x[i] = (1. + x[i])/2.;
      w[i] /= 2.;
   }
   return;
}


void GaussTables(const int n, std::vector<double>& x, std::vector<double>& w)
{
   x.resize(n);
   w.resize(n);

   if ( n == 1 )
   {
      x[0] = 0.000000000000000000000000000000;

      w[0] = 2.000000000000000000000000000000;
   }
   else if ( n == 2 )
   {
      x[0] = -0.577350269189625764509148780502;
      x[1] = 0.577350269189625764509148780502;

      w[0] = 1.000000000000000000000000000000;
      w[1] = 1.000000000000000000000000000000;
   }
   else if ( n == 3 )
   {
      x[0] = -0.774596669241483377035853079956;
      x[1] = 0.000000000000000000000000000000;
      x[2] = 0.774596669241483377035853079956;

      w[0] = 0.555555555555555555555555555556;
      w[1] = 0.888888888888888888888888888889;
      w[2] = 0.555555555555555555555555555556;
   }
   else if ( n == 4 )
   {
      x[0] = -0.861136311594052575223946488893;
      x[1] = -0.339981043584856264802665759103;
      x[2] = 0.339981043584856264802665759103;
      x[3] = 0.861136311594052575223946488893;

      w[0] = 0.347854845137453857373063949222;
      w[1] = 0.652145154862546142626936050778;
      w[2] = 0.652145154862546142626936050778;
      w[3] = 0.347854845137453857373063949222;
   }
   else if ( n == 5 )
   {
      x[0] = -0.906179845938663992797626878299;
      x[1] = -0.538469310105683091036314420700;
      x[2] = 0.000000000000000000000000000000;
      x[3] = 0.538469310105683091036314420700;
      x[4] = 0.906179845938663992797626878299;

      w[0] = 0.236926885056189087514264040720;
      w[1] = 0.478628670499366468041291514836;
      w[2] = 0.568888888888888888888888888889;
      w[3] = 0.478628670499366468041291514836;
      w[4] = 0.236926885056189087514264040720;
   }
   else if ( n == 6 )
   {
      x[0] = -0.932469514203152027812301554494;
      x[1] = -0.661209386466264513661399595020;
      x[2] = -0.238619186083196908630501721681;
      x[3] = 0.238619186083196908630501721681;
      x[4] = 0.661209386466264513661399595020;
      x[5] = 0.932469514203152027812301554494;

      w[0] = 0.171324492379170345040296142173;
      w[1] = 0.360761573048138607569833513838;
      w[2] = 0.467913934572691047389870343990;
      w[3] = 0.467913934572691047389870343990;
      w[4] = 0.360761573048138607569833513838;
      w[5] = 0.171324492379170345040296142173;
   }
   else if ( n == 7 )
   {
      x[0] = -0.949107912342758524526189684048;
      x[1] = -0.741531185599394439863864773281;
      x[2] = -0.405845151377397166906606412077;
      x[3] = 0.000000000000000000000000000000;
      x[4] = 0.405845151377397166906606412077;
      x[5] = 0.741531185599394439863864773281;
      x[6] = 0.949107912342758524526189684048;

      w[0] = 0.129484966168869693270611432679;
      w[1] = 0.279705391489276667901467771424;
      w[2] = 0.381830050505118944950369775489;
      w[3] = 0.417959183673469387755102040816;
      w[4] = 0.381830050505118944950369775489;
      w[5] = 0.279705391489276667901467771424;
      w[6] = 0.129484966168869693270611432679;
   }
   else if ( n == 8 )
   {
      x[0] = -0.960289856497536231683560868569;
      x[1] = -0.796666477413626739591553936476;
      x[2] = -0.525532409916328985817739049189;
      x[3] = -0.183434642495649804939476142360;
      x[4] = 0.183434642495649804939476142360;
      x[5] = 0.525532409916328985817739049189;
      x[6] = 0.796666477413626739591553936476;
      x[7] = 0.960289856497536231683560868569;

      w[0] = 0.101228536290376259152531354310;
      w[1] = 0.222381034453374470544355994426;
      w[2] = 0.313706645877887287337962201987;
      w[3] = 0.362683783378361982965150449277;
      w[4] = 0.362683783378361982965150449277;
      w[5] = 0.313706645877887287337962201987;
      w[6] = 0.222381034453374470544355994426;
      w[7] = 0.101228536290376259152531354310;
   }
   else if ( n == 9 )
   {
      x[0] = -0.968160239507626089835576203;
      x[1] = -0.836031107326635794299429788;
      x[2] = -0.613371432700590397308702039;
      x[3] = -0.324253423403808929038538015;
      x[4] = 0.000000000000000000000000000;
      x[5] = 0.324253423403808929038538015;
      x[6] = 0.613371432700590397308702039;
      x[7] = 0.836031107326635794299429788;
      x[8] = 0.968160239507626089835576203;

      w[0] = 0.081274388361574411971892158111;
      w[1] = 0.18064816069485740405847203124;
      w[2] = 0.26061069640293546231874286942;
      w[3] = 0.31234707704000284006863040658;
      w[4] = 0.33023935500125976316452506929;
      w[5] = 0.31234707704000284006863040658;
      w[6] = 0.26061069640293546231874286942;
      w[7] = 0.18064816069485740405847203124;
      w[8] = 0.081274388361574411971892158111;
   }
   else if ( n == 10 )
   {
      x[0] = -0.973906528517171720077964012;
      x[1] = -0.865063366688984510732096688;
      x[2] = -0.679409568299024406234327365;
      x[3] = -0.433395394129247190799265943;
      x[4] = -0.148874338981631210884826001;
      x[5] = 0.148874338981631210884826001;
      x[6] = 0.433395394129247190799265943;
      x[7] = 0.679409568299024406234327365;
      x[8] = 0.865063366688984510732096688;
      x[9] = 0.973906528517171720077964012;

      w[0] = 0.066671344308688137593568809893;
      w[1] = 0.14945134915058059314577633966;
      w[2] = 0.21908636251598204399553493423;
      w[3] = 0.26926671930999635509122692157;
      w[4] = 0.29552422471475287017389299465;
      w[5] = 0.29552422471475287017389299465;
      w[6] = 0.26926671930999635509122692157;
      w[7] = 0.21908636251598204399553493423;
      w[8] = 0.14945134915058059314577633966;
      w[9] = 0.066671344308688137593568809893;
   }
   else if ( n == 11 )
   {
      x[0] = -0.978228658146056992803938001;
      x[1] = -0.887062599768095299075157769;
      x[2] = -0.730152005574049324093416252;
      x[3] = -0.519096129206811815925725669;
      x[4] = -0.269543155952344972331531985;
      x[5] = 0.000000000000000000000000000;
      x[6] = 0.269543155952344972331531985;
      x[7] = 0.519096129206811815925725669;
      x[8] = 0.730152005574049324093416252;
      x[9] = 0.887062599768095299075157769;
      x[10] = 0.978228658146056992803938001;

      w[0] = 0.055668567116173666482753720443;
      w[1] = 0.12558036946490462463469429922;
      w[2] = 0.18629021092773425142609764143;
      w[3] = 0.23319376459199047991852370484;
      w[4] = 0.26280454451024666218068886989;
      w[5] = 0.27292508677790063071448352834;
      w[6] = 0.26280454451024666218068886989;
      w[7] = 0.23319376459199047991852370484;
      w[8] = 0.18629021092773425142609764143;
      w[9] = 0.12558036946490462463469429922;
      w[10] = 0.055668567116173666482753720443;
   }
   else if ( n == 12 )
   {
      x[0] = -0.981560634246719250690549090;
      x[1] = -0.904117256370474856678465866;
      x[2] = -0.769902674194304687036893833;
      x[3] = -0.587317954286617447296702419;
      x[4] = -0.367831498998180193752691537;
      x[5] = -0.125233408511468915472441369;
      x[6] = 0.125233408511468915472441369;
      x[7] = 0.367831498998180193752691537;
      x[8] = 0.587317954286617447296702419;
      x[9] = 0.769902674194304687036893833;
      x[10] = 0.904117256370474856678465866;
      x[11] = 0.981560634246719250690549090;

      w[0] = 0.047175336386511827194615961485;
      w[1] = 0.10693932599531843096025471819;
      w[2] = 0.16007832854334622633465252954;
      w[3] = 0.20316742672306592174906445581;
      w[4] = 0.23349253653835480876084989892;
      w[5] = 0.24914704581340278500056243604;
      w[6] = 0.24914704581340278500056243604;
      w[7] = 0.23349253653835480876084989892;
      w[8] = 0.20316742672306592174906445581;
      w[9] = 0.16007832854334622633465252954;
      w[10] = 0.10693932599531843096025471819;
      w[11] = 0.047175336386511827194615961485;
   }
   else if ( n == 13 )
   {
      x[0] = -0.984183054718588149472829449;
      x[1] = -0.917598399222977965206547837;
      x[2] = -0.801578090733309912794206490;
      x[3] = -0.642349339440340220643984607;
      x[4] = -0.448492751036446852877912852;
      x[5] = -0.230458315955134794065528121;
      x[6] = 0.000000000000000000000000000;
      x[7] = 0.230458315955134794065528121;
      x[8] = 0.448492751036446852877912852;
      x[9] = 0.642349339440340220643984607;
      x[10] = 0.80157809073330991279420649;
      x[11] = 0.91759839922297796520654784;
      x[12] = 0.98418305471858814947282945;

      w[0] = 0.040484004765315879520021592201;
      w[1] = 0.092121499837728447914421775954;
      w[2] = 0.13887351021978723846360177687;
      w[3] = 0.17814598076194573828004669200;
      w[4] = 0.20781604753688850231252321931;
      w[5] = 0.22628318026289723841209018604;
      w[6] = 0.23255155323087391019458951527;
      w[7] = 0.22628318026289723841209018604;
      w[8] = 0.20781604753688850231252321931;
      w[9] = 0.17814598076194573828004669200;
      w[10] = 0.13887351021978723846360177687;
      w[11] = 0.092121499837728447914421775954;
      w[12] = 0.040484004765315879520021592201;
   }
   else if ( n == 14 )
   {
      x[0] = -0.986283808696812338841597267;
      x[1] = -0.928434883663573517336391139;
      x[2] = -0.827201315069764993189794743;
      x[3] = -0.687292904811685470148019803;
      x[4] = -0.515248636358154091965290719;
      x[5] = -0.319112368927889760435671824;
      x[6] = -0.108054948707343662066244650;
      x[7] = 0.108054948707343662066244650;
      x[8] = 0.31911236892788976043567182;
      x[9] = 0.51524863635815409196529072;
      x[10] = 0.68729290481168547014801980;
      x[11] = 0.82720131506976499318979474;
      x[12] = 0.92843488366357351733639114;
      x[13] = 0.98628380869681233884159727;

      w[0] = 0.035119460331751863031832876138;
      w[1] = 0.08015808715976020980563327706;
      w[2] = 0.12151857068790318468941480907;
      w[3] = 0.15720316715819353456960193862;
      w[4] = 0.18553839747793781374171659013;
      w[5] = 0.20519846372129560396592406566;
      w[6] = 0.21526385346315779019587644332;
      w[7] = 0.21526385346315779019587644332;
      w[8] = 0.20519846372129560396592406566;
      w[9] = 0.18553839747793781374171659013;
      w[10] = 0.15720316715819353456960193862;
      w[11] = 0.12151857068790318468941480907;
      w[12] = 0.08015808715976020980563327706;
      w[13] = 0.035119460331751863031832876138;
   }
   else if ( n == 15 )
   {
      x[0] = -0.987992518020485428489565719;
      x[1] = -0.937273392400705904307758948;
      x[2] = -0.848206583410427216200648321;
      x[3] = -0.724417731360170047416186055;
      x[4] = -0.570972172608538847537226737;
      x[5] = -0.394151347077563369897207371;
      x[6] = -0.201194093997434522300628303;
      x[7] = 0.00000000000000000000000000;
      x[8] = 0.20119409399743452230062830;
      x[9] = 0.39415134707756336989720737;
      x[10] = 0.57097217260853884753722674;
      x[11] = 0.72441773136017004741618605;
      x[12] = 0.84820658341042721620064832;
      x[13] = 0.93727339240070590430775895;
      x[14] = 0.98799251802048542848956572;

      w[0] = 0.030753241996117268354628393577;
      w[1] = 0.070366047488108124709267416451;
      w[2] = 0.107159220467171935011869546686;
      w[3] = 0.13957067792615431444780479451;
      w[4] = 0.16626920581699393355320086048;
      w[5] = 0.18616100001556221102680056187;
      w[6] = 0.19843148532711157645611832644;
      w[7] = 0.20257824192556127288062019997;
      w[8] = 0.19843148532711157645611832644;
      w[9] = 0.18616100001556221102680056187;
      w[10] = 0.16626920581699393355320086048;
      w[11] = 0.13957067792615431444780479451;
      w[12] = 0.107159220467171935011869546686;
      w[13] = 0.070366047488108124709267416451;
      w[14] = 0.030753241996117268354628393577;
   }
   else if ( n == 16 )
   {
      x[0] = -0.989400934991649932596154173;
      x[1] = -0.944575023073232576077988416;
      x[2] = -0.865631202387831743880467898;
      x[3] = -0.755404408355003033895101195;
      x[4] = -0.617876244402643748446671764;
      x[5] = -0.458016777657227386342419443;
      x[6] = -0.281603550779258913230460501;
      x[7] = -0.09501250983763744018531934;
      x[8] = 0.09501250983763744018531934;
      x[9] = 0.28160355077925891323046050;
      x[10] = 0.45801677765722738634241944;
      x[11] = 0.61787624440264374844667176;
      x[12] = 0.75540440835500303389510119;
      x[13] = 0.86563120238783174388046790;
      x[14] = 0.94457502307323257607798842;
      x[15] = 0.98940093499164993259615417;

      w[0] = 0.027152459411754094851780572456;
      w[1] = 0.062253523938647892862843836994;
      w[2] = 0.09515851168249278480992510760;
      w[3] = 0.12462897125553387205247628219;
      w[4] = 0.14959598881657673208150173055;
      w[5] = 0.16915651939500253818931207903;
      w[6] = 0.18260341504492358886676366797;
      w[7] = 0.18945061045506849628539672321;
      w[8] = 0.18945061045506849628539672321;
      w[9] = 0.18260341504492358886676366797;
      w[10] = 0.16915651939500253818931207903;
      w[11] = 0.14959598881657673208150173055;
      w[12] = 0.12462897125553387205247628219;
      w[13] = 0.09515851168249278480992510760;
      w[14] = 0.062253523938647892862843836994;
      w[15] = 0.027152459411754094851780572456;
   }
   else if ( n == 17 )
   {
      x[0] = -0.990575475314417335675434020;
      x[1] = -0.950675521768767761222716958;
      x[2] = -0.880239153726985902122955694;
      x[3] = -0.781514003896801406925230056;
      x[4] = -0.657671159216690765850302217;
      x[5] = -0.512690537086476967886246569;
      x[6] = -0.35123176345387631529718552;
      x[7] = -0.17848418149584785585067749;
      x[8] = 0.00000000000000000000000000;
      x[9] = 0.17848418149584785585067749;
      x[10] = 0.35123176345387631529718552;
      x[11] = 0.51269053708647696788624657;
      x[12] = 0.65767115921669076585030222;
      x[13] = 0.78151400389680140692523006;
      x[14] = 0.88023915372698590212295569;
      x[15] = 0.95067552176876776122271696;
      x[16] = 0.99057547531441733567543402;

      w[0] = 0.024148302868547931960110026288;
      w[1] = 0.055459529373987201129440165359;
      w[2] = 0.085036148317179180883535370191;
      w[3] = 0.111883847193403971094788385626;
      w[4] = 0.13513636846852547328631998170;
      w[5] = 0.15404576107681028808143159480;
      w[6] = 0.16800410215645004450997066379;
      w[7] = 0.17656270536699264632527099011;
      w[8] = 0.17944647035620652545826564426;
      w[9] = 0.17656270536699264632527099011;
      w[10] = 0.16800410215645004450997066379;
      w[11] = 0.15404576107681028808143159480;
      w[12] = 0.13513636846852547328631998170;
      w[13] = 0.111883847193403971094788385626;
      w[14] = 0.085036148317179180883535370191;
      w[15] = 0.055459529373987201129440165359;
      w[16] = 0.024148302868547931960110026288;
   }
   else if ( n == 18 )
   {
      x[0] = -0.991565168420930946730016005;
      x[1] = -0.955823949571397755181195893;
      x[2] = -0.892602466497555739206060591;
      x[3] = -0.803704958972523115682417455;
      x[4] = -0.691687043060353207874891081;
      x[5] = -0.55977083107394753460787155;
      x[6] = -0.41175116146284264603593179;
      x[7] = -0.25188622569150550958897285;
      x[8] = -0.08477501304173530124226185;
      x[9] = 0.08477501304173530124226185;
      x[10] = 0.25188622569150550958897285;
      x[11] = 0.41175116146284264603593179;
      x[12] = 0.55977083107394753460787155;
      x[13] = 0.69168704306035320787489108;
      x[14] = 0.80370495897252311568241746;
      x[15] = 0.89260246649755573920606059;
      x[16] = 0.95582394957139775518119589;
      x[17] = 0.99156516842093094673001600;

      w[0] = 0.021616013526483310313342710266;
      w[1] = 0.049714548894969796453334946203;
      w[2] = 0.07642573025488905652912967762;
      w[3] = 0.10094204410628716556281398492;
      w[4] = 0.12255520671147846018451912680;
      w[5] = 0.14064291467065065120473130375;
      w[6] = 0.15468467512626524492541800384;
      w[7] = 0.16427648374583272298605377647;
      w[8] = 0.16914238296314359184065647013;
      w[9] = 0.16914238296314359184065647013;
      w[10] = 0.16427648374583272298605377647;
      w[11] = 0.15468467512626524492541800384;
      w[12] = 0.14064291467065065120473130375;
      w[13] = 0.12255520671147846018451912680;
      w[14] = 0.10094204410628716556281398492;
      w[15] = 0.07642573025488905652912967762;
      w[16] = 0.049714548894969796453334946203;
      w[17] = 0.021616013526483310313342710266;
   }
   else if ( n == 19 )
   {
      x[0] = -0.992406843843584403189017670;
      x[1] = -0.960208152134830030852778841;
      x[2] = -0.903155903614817901642660929;
      x[3] = -0.822714656537142824978922487;
      x[4] = -0.72096617733522937861709586;
      x[5] = -0.60054530466168102346963816;
      x[6] = -0.46457074137596094571726715;
      x[7] = -0.31656409996362983199011733;
      x[8] = -0.16035864564022537586809612;
      x[9] = 0.00000000000000000000000000;
      x[10] = 0.16035864564022537586809612;
      x[11] = 0.31656409996362983199011733;
      x[12] = 0.46457074137596094571726715;
      x[13] = 0.60054530466168102346963816;
      x[14] = 0.72096617733522937861709586;
      x[15] = 0.82271465653714282497892249;
      x[16] = 0.90315590361481790164266093;
      x[17] = 0.96020815213483003085277884;
      x[18] = 0.99240684384358440318901767;

      w[0] = 0.019461788229726477036312041464;
      w[1] = 0.044814226765699600332838157402;
      w[2] = 0.069044542737641226580708258006;
      w[3] = 0.091490021622449999464462094124;
      w[4] = 0.111566645547333994716023901682;
      w[5] = 0.12875396253933622767551578486;
      w[6] = 0.14260670217360661177574610944;
      w[7] = 0.15276604206585966677885540090;
      w[8] = 0.15896884339395434764995643946;
      w[9] = 0.16105444984878369597916362532;
      w[10] = 0.15896884339395434764995643946;
      w[11] = 0.15276604206585966677885540090;
      w[12] = 0.14260670217360661177574610944;
      w[13] = 0.12875396253933622767551578486;
      w[14] = 0.111566645547333994716023901682;
      w[15] = 0.091490021622449999464462094124;
      w[16] = 0.069044542737641226580708258006;
      w[17] = 0.044814226765699600332838157402;
      w[18] = 0.019461788229726477036312041464;
   }
   else if ( n == 20 )
   {
      x[0] = -0.993128599185094924786122388;
      x[1] = -0.963971927277913791267666131;
      x[2] = -0.912234428251325905867752441;
      x[3] = -0.83911697182221882339452906;
      x[4] = -0.74633190646015079261430507;
      x[5] = -0.63605368072651502545283670;
      x[6] = -0.51086700195082709800436405;
      x[7] = -0.37370608871541956067254818;
      x[8] = -0.22778585114164507808049620;
      x[9] = -0.07652652113349733375464041;
      x[10] = 0.07652652113349733375464041;
      x[11] = 0.22778585114164507808049620;
      x[12] = 0.37370608871541956067254818;
      x[13] = 0.51086700195082709800436405;
      x[14] = 0.63605368072651502545283670;
      x[15] = 0.74633190646015079261430507;
      x[16] = 0.83911697182221882339452906;
      x[17] = 0.91223442825132590586775244;
      x[18] = 0.96397192727791379126766613;
      x[19] = 0.99312859918509492478612239;

      w[0] = 0.017614007139152118311861962352;
      w[1] = 0.040601429800386941331039952275;
      w[2] = 0.062672048334109063569506535187;
      w[3] = 0.08327674157670474872475814322;
      w[4] = 0.10193011981724043503675013548;
      w[5] = 0.11819453196151841731237737771;
      w[6] = 0.13168863844917662689849449975;
      w[7] = 0.14209610931838205132929832507;
      w[8] = 0.14917298647260374678782873700;
      w[9] = 0.15275338713072585069808433195;
      w[10] = 0.15275338713072585069808433195;
      w[11] = 0.14917298647260374678782873700;
      w[12] = 0.14209610931838205132929832507;
      w[13] = 0.13168863844917662689849449975;
      w[14] = 0.11819453196151841731237737771;
      w[15] = 0.10193011981724043503675013548;
      w[16] = 0.08327674157670474872475814322;
      w[17] = 0.062672048334109063569506535187;
      w[18] = 0.040601429800386941331039952275;
      w[19] = 0.017614007139152118311861962352;
   }
   Scale(x,w);
   return;
}

void LobattoTables(const int n, std::vector<double>& x,
                   std::vector<double>& w)
{
   x.resize(n);
   w.resize(n);
   if ( n == 1 )
   {
      x[0] = 0.0;
      w[0] = 2.0;
   }
   else if ( n == 2 )
   {
      x[0] =  - 1.0E+00;
      x[1] =    1.0E+00;

      w[0] =  1.0E+00;
      w[1] =  1.0E+00;
   }
   else if ( n == 3 )
   {
      x[0] =  - 1.0E+00;
      x[1] =    0.0E+00;
      x[2] =    1.0E+00;

      w[0] =  1.0 / 3.0E+00;
      w[1] =  4.0 / 3.0E+00;
      w[2] =  1.0 / 3.0E+00;
   }
   else if ( n == 4 )
   {
      x[0] =  - 1.0E+00;
      x[1] =  - 0.447213595499957939281834733746E+00;
      x[2] =    0.447213595499957939281834733746E+00;
      x[3] =    1.0E+00;

      w[0] =  1.0E+00 / 6.0E+00;
      w[1] =  5.0E+00 / 6.0E+00;
      w[2] =  5.0E+00 / 6.0E+00;
      w[3] =  1.0E+00 / 6.0E+00;
   }
   else if ( n == 5 )
   {
      x[0] =  - 1.0E+00;
      x[1] =  - 0.654653670707977143798292456247E+00;
      x[2] =    0.0E+00;
      x[3] =    0.654653670707977143798292456247E+00;
      x[4] =    1.0E+00;

      w[0] =  9.0E+00 / 90.0E+00;
      w[1] = 49.0E+00 / 90.0E+00;
      w[2] = 64.0E+00 / 90.0E+00;
      w[3] = 49.0E+00 / 90.0E+00;
      w[4] =  9.0E+00 / 90.0E+00;
   }
   else if ( n == 6 )
   {
      x[0] =  - 1.0E+00;
      x[1] =  - 0.765055323929464692851002973959E+00;
      x[2] =  - 0.285231516480645096314150994041E+00;
      x[3] =    0.285231516480645096314150994041E+00;
      x[4] =    0.765055323929464692851002973959E+00;
      x[5] =    1.0E+00;

      w[0] =  0.066666666666666666666666666667E+00;
      w[1] =  0.378474956297846980316612808212E+00;
      w[2] =  0.554858377035486353016720525121E+00;
      w[3] =  0.554858377035486353016720525121E+00;
      w[4] =  0.378474956297846980316612808212E+00;
      w[5] =  0.066666666666666666666666666667E+00;
   }
   else if ( n == 7 )
   {
      x[0] =  - 1.0E+00;
      x[1] =  - 0.830223896278566929872032213967E+00;
      x[2] =  - 0.468848793470714213803771881909E+00;
      x[3] =    0.0E+00;
      x[4] =    0.468848793470714213803771881909E+00;
      x[5] =    0.830223896278566929872032213967E+00;
      x[6] =    1.0E+00;

      w[0] =  0.476190476190476190476190476190E-01;
      w[1] =  0.276826047361565948010700406290E+00;
      w[2] =  0.431745381209862623417871022281E+00;
      w[3] =  0.487619047619047619047619047619E+00;
      w[4] =  0.431745381209862623417871022281E+00;
      w[5] =  0.276826047361565948010700406290E+00;
      w[6] =  0.476190476190476190476190476190E-01;
   }
   else if ( n == 8 )
   {
      x[0] =  - 1.0E+00;
      x[1] =  - 0.871740148509606615337445761221E+00;
      x[2] =  - 0.591700181433142302144510731398E+00;
      x[3] =  - 0.209299217902478868768657260345E+00;
      x[4] =    0.209299217902478868768657260345E+00;
      x[5] =    0.591700181433142302144510731398E+00;
      x[6] =    0.871740148509606615337445761221E+00;
      x[7] =    1.0E+00;

      w[0] =  0.357142857142857142857142857143E-01;
      w[1] =  0.210704227143506039382991065776E+00;
      w[2] =  0.341122692483504364764240677108E+00;
      w[3] =  0.412458794658703881567052971402E+00;
      w[4] =  0.412458794658703881567052971402E+00;
      w[5] =  0.341122692483504364764240677108E+00;
      w[6] =  0.210704227143506039382991065776E+00;
      w[7] =  0.357142857142857142857142857143E-01;
   }
   else if ( n == 9 )
   {
      x[0] =  - 1.0E+00;
      x[1] =  - 0.899757995411460157312345244418E+00;
      x[2] =  - 0.677186279510737753445885427091E+00;
      x[3] =  - 0.363117463826178158710752068709E+00;
      x[4] =    0.0E+00;
      x[5] =    0.363117463826178158710752068709E+00;
      x[6] =    0.677186279510737753445885427091E+00;
      x[7] =    0.899757995411460157312345244418E+00;
      x[8] =    1.0E+00;

      w[0] =  0.277777777777777777777777777778E-01;
      w[1] =  0.165495361560805525046339720029E+00;
      w[2] =  0.274538712500161735280705618579E+00;
      w[3] =  0.346428510973046345115131532140E+00;
      w[4] =  0.371519274376417233560090702948E+00;
      w[5] =  0.346428510973046345115131532140E+00;
      w[6] =  0.274538712500161735280705618579E+00;
      w[7] =  0.165495361560805525046339720029E+00;
      w[8] =  0.277777777777777777777777777778E-01;
   }
   else if ( n == 10 )
   {
      x[0] =  - 1.0E+00;
      x[1] =  - 0.919533908166458813828932660822E+00;
      x[2] =  - 0.738773865105505075003106174860E+00;
      x[3] =  - 0.477924949810444495661175092731E+00;
      x[4] =  - 0.165278957666387024626219765958E+00;
      x[5] =    0.165278957666387024626219765958E+00;
      x[6] =    0.477924949810444495661175092731E+00;
      x[7] =    0.738773865105505075003106174860E+00;
      x[8] =    0.919533908166458813828932660822E+00;
      x[9] =   1.0E+00;

      w[0] =  0.222222222222222222222222222222E-01;
      w[1] =  0.133305990851070111126227170755E+00;
      w[2] =  0.224889342063126452119457821731E+00;
      w[3] =  0.292042683679683757875582257374E+00;
      w[4] =  0.327539761183897456656510527917E+00;
      w[5] =  0.327539761183897456656510527917E+00;
      w[6] =  0.292042683679683757875582257374E+00;
      w[7] =  0.224889342063126452119457821731E+00;
      w[8] =  0.133305990851070111126227170755E+00;
      w[9] = 0.222222222222222222222222222222E-01;
   }
   else if ( n == 11 )
   {
      x[0] =  - 1.0E+00;
      x[1] =  - 0.934001430408059134332274136099E+00;
      x[2] =  - 0.784483473663144418622417816108E+00;
      x[3] =  - 0.565235326996205006470963969478E+00;
      x[4] =  - 0.295758135586939391431911515559E+00;
      x[5] =    0.0E+00;
      x[6] =    0.295758135586939391431911515559E+00;
      x[7] =    0.565235326996205006470963969478E+00;
      x[8] =    0.784483473663144418622417816108E+00;
      x[9] =   0.934001430408059134332274136099E+00;
      x[10] =   1.0E+00;

      w[0] =  0.181818181818181818181818181818E-01;
      w[1] =  0.109612273266994864461403449580E+00;
      w[2] =  0.187169881780305204108141521899E+00;
      w[3] =  0.248048104264028314040084866422E+00;
      w[4] =  0.286879124779008088679222403332E+00;
      w[5] =  0.300217595455690693785931881170E+00;
      w[6] =  0.286879124779008088679222403332E+00;
      w[7] =  0.248048104264028314040084866422E+00;
      w[8] =  0.187169881780305204108141521899E+00;
      w[9] = 0.109612273266994864461403449580E+00;
      w[10] = 0.181818181818181818181818181818E-01;
   }
   else if ( n == 12 )
   {
      x[0] =  - 1.0E+00;
      x[1] =  - 0.944899272222882223407580138303E+00;
      x[2] =  - 0.819279321644006678348641581717E+00;
      x[3] =  - 0.632876153031869677662404854444E+00;
      x[4] =  - 0.399530940965348932264349791567E+00;
      x[5] =  - 0.136552932854927554864061855740E+00;
      x[6] =    0.136552932854927554864061855740E+00;
      x[7] =    0.399530940965348932264349791567E+00;
      x[8] =    0.632876153031869677662404854444E+00;
      x[9] =   0.819279321644006678348641581717E+00;
      x[10] =   0.944899272222882223407580138303E+00;
      x[11] =   1.0E+00;

      w[0] =  0.151515151515151515151515151515E-01;
      w[1] =  0.916845174131961306683425941341E-01;
      w[2] =  0.157974705564370115164671062700E+00;
      w[3] =  0.212508417761021145358302077367E+00;
      w[4] =  0.251275603199201280293244412148E+00;
      w[5] =  0.271405240910696177000288338500E+00;
      w[6] =  0.271405240910696177000288338500E+00;
      w[7] =  0.251275603199201280293244412148E+00;
      w[8] =  0.212508417761021145358302077367E+00;
      w[9] = 0.157974705564370115164671062700E+00;
      w[10] = 0.916845174131961306683425941341E-01;
      w[11] = 0.151515151515151515151515151515E-01;
   }
   else if ( n == 13 )
   {
      x[0] =  - 1.0E+00;
      x[1] =  - 0.953309846642163911896905464755E+00;
      x[2] =  - 0.846347564651872316865925607099E+00;
      x[3] =  - 0.686188469081757426072759039566E+00;
      x[4] =  - 0.482909821091336201746937233637E+00;
      x[5] =  - 0.249286930106239992568673700374E+00;
      x[6] =    0.0E+00;
      x[7] =    0.249286930106239992568673700374E+00;
      x[8] =    0.482909821091336201746937233637E+00;
      x[9] =   0.686188469081757426072759039566E+00;
      x[10] =   0.846347564651872316865925607099E+00;
      x[11] =   0.953309846642163911896905464755E+00;
      x[12] =   1.0E+00;

      w[0] =  0.128205128205128205128205128205E-01;
      w[1] =  0.778016867468189277935889883331E-01;
      w[2] =  0.134981926689608349119914762589E+00;
      w[3] =  0.183646865203550092007494258747E+00;
      w[4] =  0.220767793566110086085534008379E+00;
      w[5] =  0.244015790306676356458578148360E+00;
      w[6] =  0.251930849333446736044138641541E+00;
      w[7] =  0.244015790306676356458578148360E+00;
      w[8] =  0.220767793566110086085534008379E+00;
      w[9] = 0.183646865203550092007494258747E+00;
      w[10] = 0.134981926689608349119914762589E+00;
      w[11] = 0.778016867468189277935889883331E-01;
      w[12] = 0.128205128205128205128205128205E-01;
   }
   else if ( n == 14 )
   {
      x[0] =  - 1.0E+00;
      x[1] =  - 0.959935045267260901355100162015E+00;
      x[2] =  - 0.867801053830347251000220202908E+00;
      x[3] =  - 0.728868599091326140584672400521E+00;
      x[4] =  - 0.550639402928647055316622705859E+00;
      x[5] =  - 0.342724013342712845043903403642E+00;
      x[6] =  - 0.116331868883703867658776709736E+00;
      x[7] =    0.116331868883703867658776709736E+00;
      x[8] =    0.342724013342712845043903403642E+00;
      x[9] =   0.550639402928647055316622705859E+00;
      x[10] =   0.728868599091326140584672400521E+00;
      x[11] =   0.867801053830347251000220202908E+00;
      x[12] =   0.959935045267260901355100162015E+00;
      x[13] =   1.0E+00;

      w[0] =  0.109890109890109890109890109890E-01;
      w[1] =  0.668372844976812846340706607461E-01;
      w[2] =  0.116586655898711651540996670655E+00;
      w[3] =  0.160021851762952142412820997988E+00;
      w[4] =  0.194826149373416118640331778376E+00;
      w[5] =  0.219126253009770754871162523954E+00;
      w[6] =  0.231612794468457058889628357293E+00;
      w[7] =  0.231612794468457058889628357293E+00;
      w[8] =  0.219126253009770754871162523954E+00;
      w[9] = 0.194826149373416118640331778376E+00;
      w[10] = 0.160021851762952142412820997988E+00;
      w[11] = 0.116586655898711651540996670655E+00;
      w[12] = 0.668372844976812846340706607461E-01;
      w[13] = 0.109890109890109890109890109890E-01;
   }
   else if ( n == 15 )
   {
      x[0] =  - 1.0E+00;
      x[1] =  - 0.965245926503838572795851392070E+00;
      x[2] =  - 0.885082044222976298825401631482E+00;
      x[3] =  - 0.763519689951815200704118475976E+00;
      x[4] =  - 0.606253205469845711123529938637E+00;
      x[5] =  - 0.420638054713672480921896938739E+00;
      x[6] =  - 0.215353955363794238225679446273E+00;
      x[7] =    0.0E+00;
      x[8] =    0.215353955363794238225679446273E+00;
      x[9] =   0.420638054713672480921896938739E+00;
      x[10] =   0.606253205469845711123529938637E+00;
      x[11] =   0.763519689951815200704118475976E+00;
      x[12] =   0.885082044222976298825401631482E+00;
      x[13] =   0.965245926503838572795851392070E+00;
      x[14] =   1.0E+00;

      w[0] =  0.952380952380952380952380952381E-02;
      w[1] =  0.580298930286012490968805840253E-01;
      w[2] =  0.101660070325718067603666170789E+00;
      w[3] =  0.140511699802428109460446805644E+00;
      w[4] =  0.172789647253600949052077099408E+00;
      w[5] =  0.196987235964613356092500346507E+00;
      w[6] =  0.211973585926820920127430076977E+00;
      w[7] =  0.217048116348815649514950214251E+00;
      w[8] =  0.211973585926820920127430076977E+00;
      w[9] = 0.196987235964613356092500346507E+00;
      w[10] = 0.172789647253600949052077099408E+00;
      w[11] = 0.140511699802428109460446805644E+00;
      w[12] = 0.101660070325718067603666170789E+00;
      w[13] = 0.580298930286012490968805840253E-01;
      w[14] = 0.952380952380952380952380952381E-02;
   }
   else if ( n == 16 )
   {
      x[0] =  - 1.0E+00;
      x[1] =  - 0.969568046270217932952242738367E+00;
      x[2] =  - 0.899200533093472092994628261520E+00;
      x[3] =  - 0.792008291861815063931088270963E+00;
      x[4] =  - 0.652388702882493089467883219641E+00;
      x[5] =  - 0.486059421887137611781890785847E+00;
      x[6] =  - 0.299830468900763208098353454722E+00;
      x[7] =  - 0.101326273521949447843033005046E+00;
      x[8] =    0.101326273521949447843033005046E+00;
      x[9] =   0.299830468900763208098353454722E+00;
      x[10] =   0.486059421887137611781890785847E+00;
      x[11] =   0.652388702882493089467883219641E+00;
      x[12] =   0.792008291861815063931088270963E+00;
      x[13] =   0.899200533093472092994628261520E+00;
      x[14] =   0.969568046270217932952242738367E+00;
      x[15] =   1.0E+00;

      w[0] =  0.833333333333333333333333333333E-02;
      w[1] =  0.508503610059199054032449195655E-01;
      w[2] =  0.893936973259308009910520801661E-01;
      w[3] =  0.124255382132514098349536332657E+00;
      w[4] =  0.154026980807164280815644940485E+00;
      w[5] =  0.177491913391704125301075669528E+00;
      w[6] =  0.193690023825203584316913598854E+00;
      w[7] =  0.201958308178229871489199125411E+00;
      w[8] =  0.201958308178229871489199125411E+00;
      w[9] = 0.193690023825203584316913598854E+00;
      w[10] = 0.177491913391704125301075669528E+00;
      w[11] = 0.154026980807164280815644940485E+00;
      w[12] = 0.124255382132514098349536332657E+00;
      w[13] = 0.893936973259308009910520801661E-01;
      w[14] = 0.508503610059199054032449195655E-01;
      w[15] = 0.833333333333333333333333333333E-02;
   }
   else if ( n == 17 )
   {
      x[0] =  - 1.0E+00;
      x[1] =  - 0.973132176631418314156979501874E+00;
      x[2] =  - 0.910879995915573595623802506398E+00;
      x[3] =  - 0.815696251221770307106750553238E+00;
      x[4] =  - 0.691028980627684705394919357372E+00;
      x[5] =  - 0.541385399330101539123733407504E+00;
      x[6] =  - 0.372174433565477041907234680735E+00;
      x[7] =  - 0.189511973518317388304263014753E+00;
      x[8] =    0.0E+00;
      x[9] =   0.189511973518317388304263014753E+00;
      x[10] =   0.372174433565477041907234680735E+00;
      x[11] =   0.541385399330101539123733407504E+00;
      x[12] =   0.691028980627684705394919357372E+00;
      x[13] =   0.815696251221770307106750553238E+00;
      x[14] =   0.910879995915573595623802506398E+00;
      x[15] =   0.973132176631418314156979501874E+00;
      x[16] =   1.0E+00;

      w[0] =  0.735294117647058823529411764706E-02;
      w[1] =  0.449219405432542096474009546232E-01;
      w[2] =  0.791982705036871191902644299528E-01;
      w[3] =  0.110592909007028161375772705220E+00;
      w[4] =  0.137987746201926559056201574954E+00;
      w[5] =  0.160394661997621539516328365865E+00;
      w[6] =  0.177004253515657870436945745363E+00;
      w[7] =  0.187216339677619235892088482861E+00;
      w[8] =  0.190661874753469433299407247028E+00;
      w[9] = 0.187216339677619235892088482861E+00;
      w[10] = 0.177004253515657870436945745363E+00;
      w[11] = 0.160394661997621539516328365865E+00;
      w[12] = 0.137987746201926559056201574954E+00;
      w[13] = 0.110592909007028161375772705220E+00;
      w[14] = 0.791982705036871191902644299528E-01;
      w[15] = 0.449219405432542096474009546232E-01;
      w[16] = 0.735294117647058823529411764706E-02;
   }
   else if ( n == 18 )
   {
      x[0] =  - 1.0E+00;
      x[1] =  - 0.976105557412198542864518924342E+00;
      x[2] =  - 0.920649185347533873837854625431E+00;
      x[3] =  - 0.835593535218090213713646362328E+00;
      x[4] =  - 0.723679329283242681306210365302E+00;
      x[5] =  - 0.588504834318661761173535893194E+00;
      x[6] =  - 0.434415036912123975342287136741E+00;
      x[7] =  - 0.266362652878280984167665332026E+00;
      x[8] =  - 0.897490934846521110226450100886E-01;
      x[9] =   0.897490934846521110226450100886E-01;
      x[10] =   0.266362652878280984167665332026E+00;
      x[11] =   0.434415036912123975342287136741E+00;
      x[12] =   0.588504834318661761173535893194E+00;
      x[13] =   0.723679329283242681306210365302E+00;
      x[14] =   0.835593535218090213713646362328E+00;
      x[15] =   0.920649185347533873837854625431E+00;
      x[16] =   0.976105557412198542864518924342E+00;
      x[17] =   1.0E+00;

      w[0] =  0.653594771241830065359477124183E-02;
      w[1] =  0.399706288109140661375991764101E-01;
      w[2] =  0.706371668856336649992229601678E-01;
      w[3] =  0.990162717175028023944236053187E-01;
      w[4] =  0.124210533132967100263396358897E+00;
      w[5] =  0.145411961573802267983003210494E+00;
      w[6] =  0.161939517237602489264326706700E+00;
      w[7] =  0.173262109489456226010614403827E+00;
      w[8] =  0.179015863439703082293818806944E+00;
      w[9] = 0.179015863439703082293818806944E+00;
      w[10] = 0.173262109489456226010614403827E+00;
      w[11] = 0.161939517237602489264326706700E+00;
      w[12] = 0.145411961573802267983003210494E+00;
      w[13] = 0.124210533132967100263396358897E+00;
      w[14] = 0.990162717175028023944236053187E-01;
      w[15] = 0.706371668856336649992229601678E-01;
      w[16] = 0.399706288109140661375991764101E-01;
      w[17] = 0.653594771241830065359477124183E-02;
   }
   else if ( n == 19 )
   {
      x[0] =  - 1.0E+00;
      x[1] =  - 0.978611766222080095152634063110E+00;
      x[2] =  - 0.928901528152586243717940258797E+00;
      x[3] =  - 0.852460577796646093085955970041E+00;
      x[4] =  - 0.751494202552613014163637489634E+00;
      x[5] =  - 0.628908137265220497766832306229E+00;
      x[6] =  - 0.488229285680713502777909637625E+00;
      x[7] =  - 0.333504847824498610298500103845E+00;
      x[8] =  - 0.169186023409281571375154153445E+00;
      x[9] =   0.0E+00;
      x[10] =   0.169186023409281571375154153445E+00;
      x[11] =   0.333504847824498610298500103845E+00;
      x[12] =   0.488229285680713502777909637625E+00;
      x[13] =   0.628908137265220497766832306229E+00;
      x[14] =   0.751494202552613014163637489634E+00;
      x[15] =   0.852460577796646093085955970041E+00;
      x[16] =   0.928901528152586243717940258797E+00;
      x[17] =   0.978611766222080095152634063110E+00;
      x[18] =   1.0E+00;

      w[0] =  0.584795321637426900584795321637E-02;
      w[1] =  0.357933651861764771154255690351E-01;
      w[2] =  0.633818917626297368516956904183E-01;
      w[3] =  0.891317570992070844480087905562E-01;
      w[4] =  0.112315341477305044070910015464E+00;
      w[5] =  0.132267280448750776926046733910E+00;
      w[6] =  0.148413942595938885009680643668E+00;
      w[7] =  0.160290924044061241979910968184E+00;
      w[8] =  0.167556584527142867270137277740E+00;
      w[9] = 0.170001919284827234644672715617E+00;
      w[10] = 0.167556584527142867270137277740E+00;
      w[11] = 0.160290924044061241979910968184E+00;
      w[12] = 0.148413942595938885009680643668E+00;
      w[13] = 0.132267280448750776926046733910E+00;
      w[14] = 0.112315341477305044070910015464E+00;
      w[15] = 0.891317570992070844480087905562E-01;
      w[16] = 0.633818917626297368516956904183E-01;
      w[17] = 0.357933651861764771154255690351E-01;
      w[18] = 0.584795321637426900584795321637E-02;
   }
   else if ( n == 20 )
   {
      x[0] =  - 1.0E+00;
      x[1] =  - 0.980743704893914171925446438584E+00;
      x[2] =  - 0.935934498812665435716181584931E+00;
      x[3] =  - 0.866877978089950141309847214616E+00;
      x[4] =  - 0.775368260952055870414317527595E+00;
      x[5] =  - 0.663776402290311289846403322971E+00;
      x[6] =  - 0.534992864031886261648135961829E+00;
      x[7] =  - 0.392353183713909299386474703816E+00;
      x[8] =  - 0.239551705922986495182401356927E+00;
      x[9] = - 0.805459372388218379759445181596E-01;
      x[10] =   0.805459372388218379759445181596E-01;
      x[11] =   0.239551705922986495182401356927E+00;
      x[12] =   0.392353183713909299386474703816E+00;
      x[13] =   0.534992864031886261648135961829E+00;
      x[14] =   0.663776402290311289846403322971E+00;
      x[15] =   0.775368260952055870414317527595E+00;
      x[16] =   0.866877978089950141309847214616E+00;
      x[17] =   0.935934498812665435716181584931E+00;
      x[18] =   0.980743704893914171925446438584E+00;
      x[19] =   1.0E+00;

      w[0] =  0.526315789473684210526315789474E-02;
      w[1] =  0.322371231884889414916050281173E-01;
      w[2] =  0.571818021275668260047536271732E-01;
      w[3] =  0.806317639961196031447768461137E-01;
      w[4] =  0.101991499699450815683781205733E+00;
      w[5] =  0.120709227628674725099429705002E+00;
      w[6] =  0.136300482358724184489780792989E+00;
      w[7] =  0.148361554070916825814713013734E+00;
      w[8] =  0.156580102647475487158169896794E+00;
      w[9] = 0.160743286387845749007726726449E+00;
      w[10] = 0.160743286387845749007726726449E+00;
      w[11] = 0.156580102647475487158169896794E+00;
      w[12] = 0.148361554070916825814713013734E+00;
      w[13] = 0.136300482358724184489780792989E+00;
      w[14] = 0.120709227628674725099429705002E+00;
      w[15] = 0.101991499699450815683781205733E+00;
      w[16] = 0.806317639961196031447768461137E-01;
      w[17] = 0.571818021275668260047536271732E-01;
      w[18] = 0.322371231884889414916050281173E-01;
      w[19] = 0.526315789473684210526315789474E-02;
   }
   Scale(x,w);
}

void ClosedNewtonCotesTables(const int n, std::vector<double>& x,
                             std::vector<double>& w)
{
   x.resize(n);
   w.resize(n);
   if (n==2)
   {
      x[0] = -1.00000000000000000000;
      x[1] =  1.00000000000000000000;

      w[0] = 1.00000000000000000000;
      w[1] = 1.00000000000000000000;
   }
   else if ( n == 3 )
   {
      x[0] = -1.00000000000000000000;
      x[1] =  0.00000000000000000000;
      x[2] =  1.00000000000000000000;

      w[0] = 0.33333333333333333333;
      w[1] = 1.33333333333333333333;
      w[2] = 0.33333333333333333333;
   }
   else if ( n == 4 )
   {
      x[0] = -1.00000000000000000000;
      x[1] = -0.33333333333333333333;
      x[2] =  0.33333333333333333333;
      x[3] =  1.00000000000000000000;

      w[0] = 0.25000000000000000000;
      w[1] = 0.75000000000000000000;
      w[2] = 0.75000000000000000000;
      w[3] = 0.25000000000000000000;
   }
   else if ( n == 5 )
   {
      x[0] = -1.00000000000000000000;
      x[1] = -0.50000000000000000000;
      x[2] =  0.00000000000000000000;
      x[3] =  0.50000000000000000000;
      x[4] =  1.00000000000000000000;

      w[0] = 0.15555555555555555556;
      w[1] = 0.71111111111111111111;
      w[2] = 0.26666666666666666667;
      w[3] = 0.71111111111111111111;
      w[4] = 0.15555555555555555556;
   }
   else if ( n == 6 )
   {
      x[0] = -1.00000000000000000000;
      x[1] = -0.60000000000000000000;
      x[2] = -0.20000000000000000000;
      x[3] =  0.20000000000000000000;
      x[4] =  0.60000000000000000000;
      x[5] =  1.00000000000000000000;

      w[0] = 0.13194444444444444444;
      w[1] = 0.52083333333333333333;
      w[2] = 0.34722222222222222222;
      w[3] = 0.34722222222222222222;
      w[4] = 0.52083333333333333333;
      w[5] = 0.13194444444444444444;
   }
   else if ( n == 7 )
   {
      x[0] = -1.00000000000000000000;
      x[1] = -0.66666666666666666667;
      x[2] = -0.33333333333333333333;
      x[3] =  0.00000000000000000000;
      x[4] =  0.33333333333333333333;
      x[5] =  0.66666666666666666667;
      x[6] =  1.00000000000000000000;

      w[0] = 0.097619047619047619048;
      w[1] = 0.51428571428571428571;
      w[2] = 0.064285714285714285714;
      w[3] = 0.64761904761904761905;
      w[4] = 0.064285714285714285714;
      w[5] = 0.51428571428571428571;
      w[6] = 0.097619047619047619048;
   }
   else if ( n == 8 )
   {
      x[0] = -1.00000000000000000000;
      x[1] = -0.71428571428571428571;
      x[2] = -0.42857142857142857143;
      x[3] = -0.14285714285714285714;
      x[4] =  0.14285714285714285714;
      x[5] =  0.42857142857142857143;
      x[6] =  0.71428571428571428571;
      x[7] =  1.00000000000000000000;

      w[0] = 0.086921296296296296296;
      w[1] = 0.41400462962962962963;
      w[2] = 0.15312500000000000000;
      w[3] = 0.34594907407407407407;
      w[4] = 0.34594907407407407407;
      w[5] = 0.15312500000000000000;
      w[6] = 0.41400462962962962963;
      w[7] = 0.086921296296296296296;
   }
   else if ( n == 9 )
   {
      x[0] = -1.00000000000000000000;
      x[1] = -0.75000000000000000000;
      x[2] = -0.50000000000000000000;
      x[3] = -0.25000000000000000000;
      x[4] =  0.00000000000000000000;
      x[5] =  0.25000000000000000000;
      x[6] =  0.50000000000000000000;
      x[7] =  0.75000000000000000000;
      x[8] =  1.00000000000000000000;

      w[0] =  0.069770723104056437390;
      w[1] =  0.41537918871252204586;
      w[2] = -0.065467372134038800705;
      w[3] =  0.74045855379188712522;
      w[4] = -0.32028218694885361552;
      w[5] =  0.74045855379188712522;
      w[6] = -0.065467372134038800705;
      w[7] =  0.41537918871252204586;
      w[8] =  0.069770723104056437390;
   }
   else if ( n == 10 )
   {
      x[0] = -1.00000000000000000000;
      x[1] = -0.77777777777777777778;
      x[2] = -0.55555555555555555556;
      x[3] = -0.33333333333333333333;
      x[4] = -0.11111111111111111111;
      x[5] =  0.11111111111111111111;
      x[6] =  0.33333333333333333333;
      x[7] =  0.55555555555555555556;
      x[8] =  0.77777777777777777778;
      x[9] =  1.00000000000000000000;

      w[0] =  0.063772321428571428571;
      w[1] =  0.35136160714285714286;
      w[2] =  0.024107142857142857143;
      w[3] =  0.43178571428571428571;
      w[4] =  0.12897321428571428571;
      w[5] =  0.12897321428571428571;
      w[6] =  0.43178571428571428571;
      w[7] =  0.024107142857142857143;
      w[8] =  0.35136160714285714286;
      w[9] =  0.063772321428571428571;
   }
   Scale(x,w);
   return;
}

void OpenNewtonCotesTables(const int n, std::vector<double>& x,
                           std::vector<double>& w)
{

   double d;
   double dx = 2./(double (n+1));

   x.resize(n);
   for (int i = 0 ; i < n ; ++i)
   {
      x[i] = double(i + 1) * dx - 1.;
   }

   w.resize(n);
   if ( n == 2 )
   {
      w[0] = 1.0;
      w[1] = 1.0;
   }
   else if ( n == 3 )
   {
      d = 3.0;

      w[0] =   4.0 / d;
      w[1] = - 2.0 / d;
      w[2] =   4.0 / d;
   }
   else if ( n == 4 )
   {
      d = 12.0;

      w[0] = 11.0 / d;
      w[1] =  1.0 / d;
      w[2] =  1.0 / d;
      w[3] = 11.0 / d;
   }
   else if ( n == 5 )
   {
      d = 10.0;

      w[0] =   11.0 / d;
      w[1] = - 14.0 / d;
      w[2] =   26.0 / d;
      w[3] = - 14.0 / d;
      w[4] =   11.0 / d;
   }
   else if ( n == 6 )
   {
      d = 1440.0;

      w[0] =  1222.0 / d;
      w[1] = - 906.0 / d;
      w[2] =  1124.0 / d;
      w[3] =  1124.0 / d;
      w[4] = - 906.0 / d;
      w[5] =  1222.0 / d;
   }
   else if ( n == 7 )
   {
      d = 945.0;

      w[0] =    920.0 / d;
      w[1] = - 1908.0 / d;
      w[2] =   4392.0 / d;
      w[3] = - 4918.0 / d;
      w[4] =   4392.0 / d;
      w[5] = - 1908.0 / d;
      w[6] =    920.0 / d;
   }
   else if ( n == 8 )
   {
      d = 40320.0;

      w[0] =   32166.0 / d;
      w[1] = - 50454.0 / d;
      w[2] =   89406.0 / d;
      w[3] = - 30798.0 / d;
      w[4] = - 30798.0 / d;
      w[5] =   89406.0 / d;
      w[6] = - 50454.0 / d;
      w[7] =   32166.0 / d;
   }
   else if ( n == 9 )
   {
      d = 4536.0;

      w[0] =    4045.0 / d;
      w[1] = - 11690.0 / d;
      w[2] =   33340.0 / d;
      w[3] = - 55070.0 / d;
      w[4] =   67822.0 / d;
      w[5] = - 55070.0 / d;
      w[6] =   33340.0 / d;
      w[7] = - 11690.0 / d;
      w[8] =    4045.0 / d;
   }
   else if ( n == 10 )
   {
      w[0] =    0.758508873456792;
      w[1] =   -1.819664627425049;
      w[2] =    4.319301146384676;
      w[3] =   -4.708337742504753;
      w[4] =    2.450192350088813;
      w[5] =    2.450192350087711;
      w[6] =   -4.708337742504625;
      w[7] =    4.319301146384526;
      w[8] =   -1.819664627425028;
      w[9] =    0.758508873456790;
   }
   Scale(x,w);
   return;
}

// You typically want to start by testing things one object at a time.
TEST_CASE("1D Quadrature Functions")
{
   // This code is automatically re-executed for all of the sections.
   mfem::IntegrationRule ir;

   mfem::QuadratureFunctions1D quad_func;

   // The tests will be reported in these sections.
   SECTION("Gauss-Legendre")
   {
      const int np = 21;
      const double tol = 1.0E-14;
      for (int n = 2; n < np ; ++n)
      {
         std::vector<double> x_tbl(n,0.);
         std::vector<double> w_tbl(n,0.);
         // Tabular reference data
         GaussTables(n,x_tbl,w_tbl);

         // MFEM calculated data
         quad_func.GaussLegendre(n,&ir);

         for (int i = 0 ; i < n; ++i)
         {
            double err_x = std::fabs( ir.IntPoint(i).x - x_tbl[i] );
            double err_w = std::fabs( ir.IntPoint(i).weight - w_tbl[i] );
            if ( (err_x > tol) || (err_w > tol) )
            {
               FAIL("Gauss Legendre with " << n << " points wrong");
               break;
            }
         }
      }
   }

   SECTION("Gauss-Lobatto-Legendre")
   {
      const int np = 21;
      const double tol = 1.0E-14;
      for (int n = 2; n < np ; ++n)
      {
         std::vector<double> x_tbl(n,0.);
         std::vector<double> w_tbl(n,0.);
         // Tabular reference data
         LobattoTables(n,x_tbl,w_tbl);

         // MFEM calculated data
         quad_func.GaussLobatto(n,&ir);

         for (int i = 0 ; i < n; ++i)
         {
            double err_x = std::fabs( ir.IntPoint(i).x - x_tbl[i] );
            double err_w = std::fabs( ir.IntPoint(i).weight - w_tbl[i] );
            if ( (err_x > tol) || (err_w > tol) )
            {
               FAIL("Gauss Lobatto with " << n << " points wrong");
               break;
            }
         }
      }
   }

   SECTION("Closed Newton-Cotes")
   {
      // There is a lot of truncation error in evaluating these
      // tolerance may need to be increased, or np decreased
      const int np = 11;
      const double tol = 1.0E-14;
      for (int n = 2; n < np ; ++n)
      {
         std::vector<double> x_tbl(n,0.);
         std::vector<double> w_tbl(n,0.);
         // Tabular reference data
         ClosedNewtonCotesTables(n,x_tbl,w_tbl);

         // MFEM calculated data
         quad_func.ClosedUniform(n,&ir);

         for (int i = 0 ; i < n; ++i)
         {
            double err_x = std::fabs( ir.IntPoint(i).x - x_tbl[i] );
            double err_w = std::fabs( ir.IntPoint(i).weight - w_tbl[i] );
            if ( (err_x > tol) || (err_w > tol) )
            {
               FAIL("Closed Newton-Cotes with " << n << " points wrong");
               break;
            }
         }
      }
   }

   SECTION("Open Newton-Cotes")
   {
      // There is a lot of truncation error in evaluating these
      // tolerance may need to be increased, or np decreased
      const int np = 11;
      const double tol = 1.0E-10;
      for (int n = 2; n < np ; ++n)
      {
         std::vector<double> x_tbl(n,0.);
         std::vector<double> w_tbl(n,0.);
         // Tabular reference data
         OpenNewtonCotesTables(n,x_tbl,w_tbl);

         // MFEM calculated data
         quad_func.OpenUniform(n,&ir);

         for (int i = 0 ; i < n; ++i)
         {
            double err_x = std::fabs( ir.IntPoint(i).x - x_tbl[i] );
            double err_w = std::fabs( ir.IntPoint(i).weight - w_tbl[i] );
            if ( (err_x > tol) || (err_w > tol) )
            {
               FAIL("Open Newton-Cotes with " << n << " points wrong");
               break;
            }
         }
      }
   }
}
